home *** CD-ROM | disk | FTP | other *** search
- /*
- Commodore 64 Emulator v0.4 Earle F. Philhower III
- Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include "Processor.h"
- #include "Memory.h"
- #include "Error.h"
- #include "Resources.h"
- #include "VIC.h"
-
-
- /* This FastDraw macro courtesy of Peter Creath <peterc@gnu.ai.mit.edu> */
- /* It's much faster than my original "FastDraw" which was a misnomer */
- #define FastDraw(a, b, c) \
- { \
- thisLine=(char**)&(lineStart[(word)((a)<<3)]); \
- theseDefs=(char*)(VICCharDefs+(word)((c)<<3)); \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- }
-
- static byte *lineStart[200];
- static Rect leftRect, rightRect, topRect, botRect, sprRect;
- static BitMap spriteMap, VICMap, fullMap;
- static GrafPtr spriteGraf;
-
- extern Rect bwWindRect, bwFullRect;
-
- static Ptr NewBitMap(BitMap *theBits, Rect *rp)
- {
- theBits->rowBytes=((rp->right-rp->left+15)/16)*2;
- theBits->baseAddr=(Ptr)GetMemory(theBits->rowBytes*(rp->bottom-rp->top));
- theBits->bounds=*rp;
- return(theBits->baseAddr);
- }
-
- int BWVICInitialize()
- {
- int row;
-
- SetRect(&bwFullRect, 0, 0, 320, 200);
- SetRect(&leftRect, 0, 0, 7, 200);
- SetRect(&rightRect, 320-8, 0, 320, 200);
- SetRect(&topRect, 0, 0, 320, 4);
- SetRect(&botRect, 0, 200-4, 320, 200);
- SetRect(&sprRect, 0, 0, 24, 21);
-
- BWVICWind=GetNewWindow(kBWVIC, nil, (WindowPtr)-1L);
- if (BWVICWind==nil) return(kMissingResource);
- SetWRefCon(BWVICWind, kVICWindow);
-
-
- if (NewBitMap(&spriteMap, &sprRect)==0) return kOutOfMemory;
- if (NewBitMap(&VICMap, &bwFullRect)==0) return kOutOfMemory;
- if (NewBitMap(&fullMap, &bwFullRect)==0) return kOutOfMemory;
-
- for (row=0; row<200; row++)
- lineStart[row]=(byte *)VICMap.baseAddr+40*row;
-
- return(kNoError);
- }
-
- void ShowBWVIC()
- {
- SelectWindow(BWVICWind);
- ShowWindow(BWVICWind);
- SetPort(BWVICWind);
- }
-
- void HideBWVIC()
- {
- HideWindow(BWVICWind);
- }
-
- static void DrawSprites()
- {
- byte spriteNum, row, *spb0, *spb1, *spb2;
- word xpos, ypos, addr0, addr1, addr2;
- Rect t;
- BitMap saveMap;
-
- CopyBits(&VICMap,&fullMap,&bwFullRect,&bwFullRect,srcCopy,nil);
- saveMap = qd.thePort->portBits;
- SetPortBits(&spriteMap);
- for (spriteNum=0; spriteNum<8; spriteNum++)
- if (VICRegister[0x15]&(1<<spriteNum))
- {
- xpos = (VICRegister[0x00+spriteNum*2]-24);
- xpos += (VICRegister[0x10]&(1<<spriteNum))?256:0;
- ypos = VICRegister[0x01+spriteNum*2]-50;
-
- t.top=ypos;
- t.left=xpos;
- t.right=t.left+24+((VICRegister[0x1d]&(1<<spriteNum))?24:0);
- t.bottom=t.top+21+((VICRegister[0x17]&(1<<spriteNum))?21:0);
-
- addr0 = VICAddrBase+RAM[VICScreenPage+1016+spriteNum]*64;
- addr1=addr0+1;
- addr2=addr0+2;
-
- spb0=(byte *)spriteMap.baseAddr;
- spb1=spb0+1;
- spb2=spb0+2;
-
- for (row=0; row<21; row++)
- {
- spb0[row<<2]=RAM[addr0+row*3];
- spb1[row<<2]=RAM[addr1+row*3];
- spb2[row<<2]=RAM[addr2+row*3];
- }
- CopyBits(&spriteMap,&fullMap,&sprRect,&t,srcOr,nil);
- }
- SetPortBits(&saveMap);
- SetPort(BWVICWind);
- }
-
- static void DrawTextScreen(byte total)
- {
- word chr;
- byte row, col;
- register char **thisLine;
- register char *theseDefs;
- BitMap saveMap;
-
- row=col=0;
- saveMap=qd.thePort->portBits;
- SetPortBits(&VICMap);
-
- if (VICRegister[0x11]&32)
- {
- /* Draw Hi-Res screen *always* since that only makes sense */
- VICCharDefs=RAM+VICAddrBase+((VICRegister[0x18]&8)?8192:0);
- for (chr=0; chr<1000; chr++)
- {
- FastDraw(row,col,chr);
- col++;
- if (++col>39)
- {
- col=0;
- row++;
- }
- }
- }
- else
- {
- /* Draw the text screen */
- if (total)
- /* Draw every single character */
- for (chr=0; chr<1000; chr++)
- {
- FastDraw(row,col,RAM[chr+VICScreenPage]);
- VICText[chr]=RAM[chr+VICScreenPage];
- if (++col>39)
- {
- col=0;
- row++;
- }
- }
- else
- for (chr=0;chr<1000;chr++)
- {
- if (VICText[chr]!=RAM[chr+VICScreenPage])
- {
- FastDraw(row,col,RAM[chr+VICScreenPage]);
- VICText[chr]=RAM[chr+VICScreenPage];
- }
- if (++col>39)
- {
- col=0;
- row++;
- }
- }
- }
- SetPortBits(&saveMap);
- }
-
- static void DrawBorders()
- {
- BitMap saveMap;
-
- saveMap=qd.thePort->portBits;
- SetPortBits(&VICMap);
- if ((VICRegister[0x16]&8)==0)
- {
- FillRect(&leftRect, (ConstPatternParam)&qd.black);
- FillRect(&rightRect, (ConstPatternParam)&qd.black);
- }
- if ((VICRegister[0x11]&8)==0)
- {
- FillRect(&botRect, (ConstPatternParam)&qd.black);
- FillRect(&topRect, (ConstPatternParam)&qd.black);
- }
- SetPortBits(&saveMap);
- }
-
- static void CopyTextToScreen()
- {
- SetPort(BWVICWind);
- CopyBits(&VICMap, &(BWVICWind->portBits), &bwFullRect, &bwWindRect, srcCopy, nil);
- }
-
- static void CopySpritesToScreen()
- {
- SetPort(BWVICWind);
- CopyBits(&fullMap, &(BWVICWind->portBits), &bwFullRect, &bwWindRect, srcCopy, nil);
- }
-
- static void BlankScreen()
- {
- BitMap saveMap;
-
- saveMap = qd.thePort->portBits;
- SetPortBits(&VICMap);
- FillRect(&bwFullRect, (PatPtr)&qd.gray);
- SetPortBits(&saveMap);
- CopyTextToScreen();
- }
-
- void BWTotalRedrawVIC()
- {
- SetPort(BWVICWind);
- if ((VICRegister[0x11]&16)==0)
- {
- BlankScreen();
- return;
- }
- DrawTextScreen(1);
- DrawBorders();
- if (VICRegister[0x15])
- {
- DrawSprites();
- CopySpritesToScreen();
- }
- else CopyTextToScreen();
- }
-
- void BWRedrawVIC()
- {
- SetPort(BWVICWind);
- if ((VICRegister[0x11]&16)==0)
- {
- BlankScreen();
- return;
- }
- DrawTextScreen(0);
- DrawBorders();
- if (VICRegister[0x15])
- {
- DrawSprites();
- CopySpritesToScreen();
- }
- else CopyTextToScreen();
- }
-
-